package com.cocos.game;

import static androidx.core.content.ContextCompat.getSystemService;

import android.content.ActivityNotFoundException;
import android.content.ClipData;
import android.content.ClipboardManager;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Vibrator;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;

import androidx.browser.customtabs.CustomTabsIntent;

import com.adjust.sdk.Adjust;
import com.adjust.sdk.AdjustAttribution;
import com.cocos.lib.JsbBridgeWrapper;
import com.google.android.gms.ads.identifier.AdvertisingIdClient;

import org.json.JSONObject;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;

import com.google.android.gms.tasks.Task;
import com.google.android.play.core.review.ReviewException;
import com.google.android.play.core.review.ReviewInfo;
import com.google.android.play.core.review.ReviewManager;
import com.google.android.play.core.review.ReviewManagerFactory;
import com.google.android.play.core.review.model.ReviewErrorCode;

public class JsbHelper {
    /* 环境：0测试 1正式 */
    public static final int ENV_TYPE = 1;
    public static Context ctx;
    public static AppActivity act;
    public static String adjustAdid = "";
    public static String adjustAttrJson = "";
    public static  String GAID = "";
    private static final String TAG = "JsbHelper";
    public static boolean isConnected;
    private static Vibrator _vibrator;
    public static void checkAdid() {
        if (TextUtils.isEmpty(adjustAdid)) {
            Adjust.getAdid(adid -> {
//                Log.d(TAG, "Adjust.getAdid= "+ adid);
                JsbHelper.emit("respAdjustAdid", adid);
                adjustAdid = adid;
                // 添加 Adjust 归因回调
                Adjust.getAttribution(attribution -> {
                    setAdjustAttrJson(attribution);
                    String systemInfo = getSystemInfo();
//                    Log.d(TAG, "getSystemInfo222 "+systemInfo);
                    JsbHelper.emit("respSystemInfo", systemInfo);
                });
            });
        }
    }

    public static void emit(String event, String arg) {
        JsbBridgeWrapper jbw = JsbBridgeWrapper.getInstance();
        jbw.dispatchEventToScript(event, arg);
    }

    public static void on(String event, JsbBridgeWrapper.OnScriptEventListener func) {
        JsbBridgeWrapper.getInstance().addScriptEventListener(event, func);
    }

    public static void listenEvents() {
        JsbHelper.on("init", arg -> {
            Adjust.getAdid(adid -> {
//                Log.d(TAG, "Adjust.getAdid= "+ adid);
                JsbHelper.emit("respAdjustAdid", adid);
                adjustAdid = adid;
                // 添加 Adjust 归因回调
                Adjust.getAttribution(attribution -> {
                    setAdjustAttrJson(attribution);
                    String systemInfo = getSystemInfo();
//                    Log.d(TAG, "getSystemInfo222 "+systemInfo);
                    JsbHelper.emit("respSystemInfo", systemInfo);
                });
            });
            JsbHelper.emit("respDeviceId", getDeviceId(act));
//            Log.d(TAG, "getSystemInfo111");
            listenNetState();
            getFirebaseToken();
//            JsbHelper.getNetState(act);
            JsbHelper.emit("respSystemInfo", getSystemInfo());
        });
        getGAID(ctx);
        JsbHelper.on("callSaveImageToGallery", JsbHelper::callSaveImageToGallery);

        JsbHelper.on("callVibrate", JsbHelper::callVibrate);
        JsbHelper.on("callMailTo", JsbHelper::callMailTo);
        JsbHelper.on("callOpenUrl", JsbHelper::callOpenUrl);
        JsbHelper.on("callCopyText", JsbHelper::callCopyText);

        JsbHelper.on("callAdLoad", JsbHelper::callAdLoad);
        JsbHelper.on("callAdUserId", JsbHelper::callAdUserId);
        JsbHelper.on("callAdLoadInter", JsbHelper::callAdLoadInter);
        JsbHelper.on("callAdLoadRewarded", JsbHelper::callAdLoadRewarded);
        JsbHelper.on("callShowAdInter", JsbHelper::callShowAdInter);
        JsbHelper.on("callShowAdRewarded", JsbHelper::callShowAdRewarded);
        JsbHelper.on("callAdBanner", JsbHelper::callAdBanner);

        JsbHelper.on("callPayResume", JsbHelper::callPayResume);
        JsbHelper.on("callPayBuy", JsbHelper::callPayBuy);
        JsbHelper.on("callPayConsume", JsbHelper::callPayConsume);


        JsbHelper.on("callTDLogin", JsbHelper::callTDLogin);
        JsbHelper.on("callTDTrack", JsbHelper::callTDTrack);
        JsbHelper.on("callTDUserSet", JsbHelper::callTDUserSet);

        JsbHelper.on("callReview", JsbHelper::callReview);
    }


    public static String getDeviceId(Context context) {
        return Settings.Secure.getString(context.getContentResolver(), Settings.Secure.ANDROID_ID);
    }

    public static String getSystemInfo() {
        try {
            JSONObject jo = MyUtils.getSystemInfo(act);
            try {
                jo.put("conversationData", getAdjustAttr());
                jo.put("idfa", GAID);
            } catch (Exception e) {
            }
            return jo.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "{}";
//        Context context = act;
//        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
//        ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
//        am.getMemoryInfo(mi);
//        File filesDir = context.getFilesDir();
//        SystemInfoObj systemInfo = new SystemInfoObj();
//        systemInfo.ramInfoOccupied = Formatter.formatFileSize(context, mi.totalMem - mi.availMem);
//        systemInfo.ramInfoTotal = Formatter.formatFileSize(context, mi.totalMem);
//        systemInfo.romInfoTotal = Formatter.formatFileSize(context, filesDir.getTotalSpace());
//        systemInfo.romInfoOccupied = Formatter.formatFileSize(context, filesDir.getTotalSpace() - filesDir.getFreeSpace());
//        systemInfo.systemInfo = Build.VERSION.RELEASE;
//        systemInfo.model = Build.MODEL;
//        systemInfo.adid = adjustAdid;
//        systemInfo.ip = getIp();
//        systemInfo.udid = getUDID();
//        systemInfo.conversionData = getAdjustAttr();
//        Gson gson = new Gson();
//        String json = gson.toJson(systemInfo);
//        return json;
    }
    public static void callSaveImageToGallery(String path) {
        MyUtils.saveImageToGallery(ctx, path);
    }
    public static void callVibrate(String str) {
        if (_vibrator == null) {
            _vibrator = getSystemService(act, Vibrator.class);
        }
        if (_vibrator != null) {
            try {
                long ms = Long.parseLong(str);
                _vibrator.vibrate(ms);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    public static void callCopyText(String text) {
        ClipboardManager clipboard = (ClipboardManager) act.getSystemService(Context.CLIPBOARD_SERVICE);
        ClipData clip = ClipData.newPlainText("text", text);
        clipboard.setPrimaryClip(clip);
    }
    public static void callMailTo(String email) {
        openMail(email);
    }
    private static void openMail(String json) {
        try {
            JSONObject jo = new JSONObject(json);
            String emailStr = jo.getString("email");
            String subject = jo.getString("subject");
            String text = jo.getString("text");
            Uri uri = Uri.parse("mailto:");
            List<ApplicationInfo> applicationInfoList = act.getPackageManager().getInstalledApplications(PackageManager.MATCH_UNINSTALLED_PACKAGES);
            List<String> tempPkgNameList = new ArrayList<>();
            List<Intent> emailIntents = new ArrayList<>();
            for (ApplicationInfo info : applicationInfoList) {
                String pkgName = info.packageName;
                if (!tempPkgNameList.contains(pkgName)) {
                    tempPkgNameList.add(pkgName);
                    Intent intent = act.getPackageManager().getLaunchIntentForPackage(pkgName);
                    emailIntents.add(intent);//添加邮箱类型应用
                }
            }
            if (!emailIntents.isEmpty()) {
                String[] email = {emailStr};
                Intent intent = new Intent(Intent.ACTION_SENDTO, uri);
                intent.putExtra(Intent.EXTRA_EMAIL, email); // 收件人
                intent.putExtra(Intent.EXTRA_SUBJECT, subject); // 主题
                intent.putExtra(Intent.EXTRA_TEXT, text); // 正文
                Intent chooserIntent = Intent.createChooser(intent, "");
                if (chooserIntent != null) {
                    act.startActivity(chooserIntent);
                } else {
                    Log.d("openEmail","没有邮箱类型应用1");
                }
            } else {
                Log.d("openEmail","没有邮箱类型应用2");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private static void callOpenUrl(final String url) {
        try {
            CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
            CustomTabsIntent customTabsIntent = builder.build();
            customTabsIntent.launchUrl(act, Uri.parse(url));
        } catch (ActivityNotFoundException e) {
            Log.e("JSBridge", "Error opening url: " + e.getMessage());
        }
    }
    public static void callAdLoad(String type) {
        if (type.equals("interstitial")) {
            ApplovinHelper.instance.loadInter();
        } else if (type.equals("rewarded")){
            ApplovinHelper.instance.loadRewarded();
        } else {
            ApplovinHelper.instance.loadBanner();
        }
    }
    public static void callAdUserId(String uid) {
        ApplovinHelper.instance.setUserID(uid);
        checkAdid();
    }
    public static void callAdLoadInter(String s) {
        ApplovinHelper.instance.loadInter();
    }
    public static void callAdLoadRewarded(String s) {
        ApplovinHelper.instance.loadRewarded();
    }
    public static void callShowAdInter(String str) {
        String[] parts = str.split("\\|\\|");
//        ApplovinHelper.instance.showInterstitialAd(parts[0], parts[1]);
        Log.d(TAG, "callShowAdInter: "+parts[0]+",,,"+parts[1]+",,,"+parts[2]);
        ApplovinHelper.instance.showAd(1,parts[0],parts[1],parts[2]);
    }
    public static void callShowAdRewarded(String str) {
        String[] parts = str.split("\\|\\|");
        Log.d(TAG, "callShowAdRewarded: "+parts[0]+",,,"+parts[1]+",,,"+parts[2]);
//        ApplovinHelper.instance.showRewardedAd(parts[0], parts[1]);
        ApplovinHelper.instance.showAd(2,parts[0],parts[1],parts[2]);
    }
    public static void callAdBanner(String str) {
        Log.d(TAG, "callAdBanner: " + str);
        if (TextUtils.isEmpty(str)) {
            ApplovinHelper.instance.hideBanner();
        } else {
            String[] parts = str.split("\\|\\|");
            ApplovinHelper.instance.showBanner(parts[0],parts[1]);
        }
    }

    public static void callPayResume(String s) {
        GooglePay.instance.resumeBuy();
    }
    public static void callPayBuy(String productId) {
        GooglePay.instance.buy(productId);
    }
    public static void callPayConsume(String token) {
        GooglePay.instance.consumePay(token);
    }

    public static void callTDLogin(String s) {
        TDHelper.login(s);
    }
    public static void callTDTrack(String s) {
        String[] parts = s.split("\\|\\|");
        Log.d(TAG, "callTDTrack: "+parts[0]+",,,"+parts[1]);
        TDHelper.track(parts[0], parts[1]);
    }
    public static void callTDUserSet(String json) {
        TDHelper.userSet(json);
    }

    public static void callReview(String s){
        ReviewManager reviewManager = ReviewManagerFactory.create(act);
        Task<ReviewInfo> request = reviewManager.requestReviewFlow();
        request.addOnCompleteListener(task -> {
            if (task.isSuccessful()) {
                ReviewInfo reviewInfo = task.getResult();
                Task<Void> flow = reviewManager.launchReviewFlow(act, reviewInfo);
                flow.addOnCompleteListener(flowTask -> {
                    Log.d("JSBridge", "callReview Completed");
                });
            } else {
                Log.d("JSBridge", "callReview error");
            }
        });
    }

    public static void getGAID(Context context) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    AdvertisingIdClient.Info adInfo = AdvertisingIdClient.getAdvertisingIdInfo(context);
                    String gaid = adInfo != null ? adInfo.getId() : "";
//                    boolean isLimitAdTrackingEnabled = adInfo != null && adInfo.isLimitAdTrackingEnabled();
                    GAID = gaid;
                    Log.d(TAG, "getGAID "+gaid);
                } catch (Exception e) {
                    Log.d(TAG, "getGAID error");
                    e.printStackTrace();
                }
            }
        }).start();
    }

    public static String getIp() {
        String ip = "";
        try {
            for (Enumeration<NetworkInterface> networks = NetworkInterface.getNetworkInterfaces(); networks.hasMoreElements(); ) {
                NetworkInterface network = networks.nextElement();
                for (Enumeration<InetAddress> addresses = network.getInetAddresses(); addresses.hasMoreElements(); ) {
                    InetAddress address = addresses.nextElement();
                    if (!address.isLoopbackAddress() && address.isSiteLocalAddress()) {
                        return address.getHostAddress();
                    }
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return ip;
    }

    public static String getUDID() {
        String paramString = "";
        if (act != null) {
            paramString = Settings.Secure.getString(act.getContentResolver(), "android_id");
        }
        return paramString;
    }
    public static String getAdjustAttr() {
        return adjustAttrJson;
    }

    public static void setAdjustAttrJson(AdjustAttribution attr){
        JSONObject obj = new JSONObject();
        try {
            obj.put("trackerToken", attr.trackerToken);
            obj.put("trackerName", attr.trackerName);
            obj.put("network", attr.network);
            obj.put("campaign", attr.campaign);
            obj.put("adgroup", attr.adgroup);
            obj.put("creative", attr.creative);
            obj.put("clickLabel", attr.clickLabel);
            obj.put("adid", adjustAdid);
            obj.put("costType", attr.costType);
            obj.put("costAmount", Double.isNaN(attr.costAmount) ? 0 : attr.costAmount);
            obj.put("costCurrency", attr.costCurrency);
            obj.put("fbInstallReferrer", attr.fbInstallReferrer);
            adjustAttrJson = obj.toString();
        } catch (Exception e) {
            adjustAttrJson = obj.toString();
        }
//        Log.d(TAG, "setAdjustAttrJson result: "+adjustAttrJson);
    }
    public static void listenNetState() {
        NetworkStateReceiver networkChangeReceiver = new NetworkStateReceiver();
        IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
        act.registerReceiver(networkChangeReceiver, filter);
    }
    public static void getNetState(Context ctx) {
        ConnectivityManager connectivityManager = (ConnectivityManager) ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetwork = connectivityManager.getActiveNetworkInfo();
        boolean isConnected = activeNetwork != null && activeNetwork.isConnectedOrConnecting();
        JsbHelper.isConnected = isConnected;
        JsbHelper.emit("respNetState", isConnected? "1":"0");
    }

    private static final String PREFS_NAME = "MyPrefsFile";
    private static final String TOKEN_KEY = "FirebaseToken";
    public static String firebaseToken = "";
    public static void setFirebaseToken(String token) {
        firebaseToken = token;
        SharedPreferences sharedPreferences = ctx.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putString(TOKEN_KEY, token);
        editor.apply();
    }
    public static void getFirebaseToken() {
        SharedPreferences sharedPreferences = ctx.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
        firebaseToken = sharedPreferences.getString(TOKEN_KEY, null);
        if (!TextUtils.isEmpty(firebaseToken)) {
            JsbHelper.emit("respFirebaseToken", firebaseToken);
        }
    }
}
